package com.peng.springtest;

import com.google.common.base.Stopwatch;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;

import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * ThreadPoolTaskExcuteTest
 *
 * @author: lupeng10
 * @create: 2023-05-04 10:48
 */
@Slf4j
public class ThreadPoolTaskExecutorTest {

    private ThreadPoolTaskExecutor executor;

    @BeforeEach
    public void init() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程数
        executor.setCorePoolSize(10);
        // 最大线程数
        executor.setMaxPoolSize(20);
        // 任务队列的容量
        executor.setQueueCapacity(512);
        // 现成最大空闲时间
        executor.setKeepAliveSeconds(10);
        // 队列满了&现成都在运行任务时的拒绝策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 现成名字
        executor.setThreadNamePrefix("custom-thread-pool-");
        executor.initialize();
        this.executor = executor;
    }


    @Test
    public void t1() {
        Stopwatch stopwatch = Stopwatch.createStarted();
        for (int i = 0; i < 10000; i++) {
            ListenableFuture<Boolean> asyncResult = executor.submitListenable(() -> {
                System.out.println("threadName: " + Thread.currentThread().getName());
                // 休息5毫秒，模拟执行
                TimeUnit.MILLISECONDS.sleep(5);
                //throw new RuntimeException("出现异常");
                return true;
            });
            asyncResult.addCallback(new ListenableFutureCallback<>() {
                @Override
                public void onFailure(@NotNull Throwable ex) {
                    log.error("出现异常", ex);
                }

                @Override
                public void onSuccess(Boolean result) {
                    log.info("运行成功: {}", result);
                }
            });
        }
        log.info("耗时 {} 毫秒", stopwatch.elapsed(TimeUnit.MILLISECONDS));
    }
}
